//
//  CTVMainMenuController.m
//  Channltv
//
//  Created by Bruno Keymolen on 06/09/07.
//  Copyright 2007 channl.tv. All rights reserved.
//

#import "CTV.h"
#import "CTVMainMenuController.h"
#import "CTVIconPreviewController.h"
#import "CTVConfigMenuController.h"
#import "CTVRootChannelMenuController.h"
#import "CTVAutoSync.h"
#import "CTVAutoUpdateController.h"


/*
 * CTVMainMenuController
 */
@implementation CTVMainMenuController


- (id) initWithScene: (BRRenderScene *) scene{
	NSLog(@"CTVMainMenuController - initWithScene");

    if( [super initWithScene: scene] == nil ){
        return ( nil );
	}
	

	m_mainMenuElements = [[NSMutableArray alloc] init];
	
	
	[self loadMenu];
	
//	[self setListTitle: @"channl.tv"];	
	[self setListTitle: @""];	
	[self setPreSelectedIndex];



	 // initialize your resources here
	[[self list] setDatasource: self];



	
	return self;
}


- (void) dealloc
{	
	NSLog(@"CTVMainMenuController - dealloc");



	[self unloadMenu:m_mainMenuElements];
	[m_mainMenuElements release];
	

	NSLog(@"CTVMainMenuController - Dealloc");	
    [super dealloc];
}



- (long) itemCount
{
    // return the number of items in your menu list here
	//return ( [menuMainItems count] );
	return ( [m_mainMenuElements count] );
}


- (id<BRMenuItemLayer>) itemForRow: (long) row
{
    // build a BRTextMenuItemLayer or a BRAdornedMenuItemLayer, etc. here
    // return that object, it will be used to display the list item.
	if ( row >= [m_mainMenuElements count] )
		return ( nil );

	id result = nil;
	
	CTVMainMenuElement* menuElement = [m_mainMenuElements objectAtIndex:row];
	
	//Type dependend decoration
	switch([menuElement type]){
		case CTVMainMenuElementType_ROOTCHANNEL:
			result = [BRAdornedMenuItemLayer adornedFolderMenuItemWithScene: [self scene]];
			[[result textItem] setTitle: [menuElement title]];
			break;
		case CTVMainMenuElementType_SYNC:
			result = [BRAdornedMenuItemLayer adornedMenuItemWithScene: [self scene]];
			[[result textItem] setTitle: [menuElement title]];
			
			if([[CTVSync GetInstance] inSync]){
				[[result textItem] setWaitSpinnerActive:TRUE];
			}else{
				[[result textItem] setWaitSpinnerActive:FALSE];
				if([[CTVSync GetInstance] syncLastError] == 0){
					[result setRightIcon : [[BRThemeInfo sharedTheme] syncLinkImageForScene: [self scene]]];				
				}else{
					[result setRightIcon : [[BRThemeInfo sharedTheme] errorIconForScene: [self scene]]];				
				}
			}			
			break;
		//Default menu item
		default:
			result = [BRAdornedMenuItemLayer adornedMenuItemWithScene: [self scene]];		
			[[result textItem] setTitle: [menuElement title]];
			break;
	}
				
	return ( result );
}





- (NSString *) titleForRow: (long) row
{
    if ( row >= [m_mainMenuElements count] )
		return ( nil );

	return ( [[m_mainMenuElements objectAtIndex: row] title] );
}


- (long) rowForTitle: (NSString *) title
{
    long result = -1;
    long i, count = [self itemCount];
    for ( i = 0; i < count; i++ )
    {
        if ( [title isEqualToString: [self titleForRow: i]] )
        {
            result = i;
            break;
        }
    }
    
    return ( result );
}



- (void) itemSelected: (long) row
{
    if ( row >= [m_mainMenuElements count] )
		return;

	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

	// This is called when the user presses play/pause on a list item
	CTVMainMenuElement* menuElement = [m_mainMenuElements objectAtIndex:row];

  	//Execute the function
	if([menuElement function] != nil){
		[self performSelector:[menuElement function] withObject:menuElement];
	}
	
	[pool release];
}


- (id<BRMediaPreviewController>) previewControllerForItem: (long) item
{
    if ( item >= [m_mainMenuElements count] )
		return nil;

    // If subclassing BRMediaMenuController, this function is called when the selection cursor
    // passes over an item.
	CTVMainMenuElement* menuElement = [m_mainMenuElements objectAtIndex:item];
		
	BRIconPreviewController* iconPreview = nil;
	CGImageRef image = nil;
	NSString* path;

	if ([menuElement iconName] != nil) {
		path = [[NSBundle bundleForClass: [self class]] pathForResource: [menuElement iconName] ofType: @"png"];
	}else{
		path = [[NSBundle bundleForClass: [self class]] pathForResource: @"ApplianceIcon" ofType: @"png"];
	}

	NSURL* url;
	url = [NSURL fileURLWithPath: path];	
	image = (CGImageRef)CreatePNGForURL( url );	
		
	if(image != nil){
		iconPreview = [[[CTVIconPreviewController alloc] initWithScene:[self scene] andImage:image ] autorelease];
		CFRelease( image );
		return ( iconPreview );
	}


    return ( nil );
}




-(void)unloadMenu:(NSMutableArray*)menuArray{
	NSEnumerator* menuElements = [menuArray objectEnumerator];
	CTVMainMenuElement* menuElement;
	while(menuElement = [menuElements nextObject]){
		[menuElement release];
	}
	[menuArray removeAllObjects];
}


-(void)loadMenu{
	CTVMainMenuElement* menuElement;
	[self unloadMenu:m_mainMenuElements];
	
	//Add the RootChannels
	NSDictionary* rootChannels = [[CTV GetInstance] rootChannels];
	
	CTVRootChannel* rootChannel;
	NSEnumerator* channelEnum = [rootChannels objectEnumerator];
	while(rootChannel = [channelEnum nextObject]){
		menuElement = [[CTVMainMenuElement alloc] init];
		[menuElement setType:CTVMainMenuElementType_ROOTCHANNEL];
		[menuElement setTitle:[rootChannel name]];
		[menuElement setRootChannel:rootChannel];
		[menuElement setFunction:@selector(showRootChannel:)];	
		[menuElement setIconName:@"channels" /*[rootChannel iconUrlString]*/];
		[m_mainMenuElements addObject:menuElement];
	}

	
	//Add Sync Now
	menuElement = [[CTVMainMenuElement alloc] init];
	[menuElement setType:CTVMainMenuElementType_SYNC];
	[menuElement setTitle:@"Sync Now"];
	[menuElement setFunction:@selector(syncNow:)];	
	[menuElement setIconName:@"synchronize"];
	[m_mainMenuElements addObject:menuElement];
	
	//Add Config
	menuElement = [[CTVMainMenuElement alloc] init];
	[menuElement setType:CTVMainMenuElementType_DEFAULT];
	[menuElement setTitle:@"Config"];
	[menuElement setFunction:@selector(config:)];	
	[menuElement setIconName:@"settings"];
	[m_mainMenuElements addObject:menuElement];
	
	[[self list] removeDividers];
	if([[[CTV GetInstance] rootChannels] count] > 0){		
		[[self list] setDividerIndex:[m_mainMenuElements count]-2];
	}
	
}







/*
 * Menu Functions
 */
-(void)syncNow:(CTVMainMenuElement*)menuElement{
	[[CTVAutoSync GetInstance] syncNow];
}


-(void)config:(CTVMainMenuElement*)menuElement{
	CTVConfigMenuController* configController = [[CTVConfigMenuController alloc] initWithScene:[self scene]];
	[[self stack] pushController: configController];
	[configController release]; //release now, pushcontroller added a retain and will release it when popped from the stack 
}


-(void)showRootChannel:(CTVMainMenuElement*)menuElement{
	CTVRootChannel* rootChannel = [menuElement rootChannel]; //A rootchannel contains a dictionary of urlString -> CTVChannel
	CTVRootChannelMenuController* controller = [[[CTVRootChannelMenuController alloc] initWithScene:[self scene] andRootChannel:rootChannel] autorelease];	
	[[self stack] pushController: controller];
}




/*
 * CTVSyncListener
 */
-(void)syncStarted{
	//Refresh menu

	//Still did not found a cleaner way to force a redraw of the menuitems
	NSArray* co = [self controls];
	int a;
	for(a=0;a<[co count];a++){
		BRControl* bc = [co objectAtIndex:a];
		[[bc layer] reload]; 
	}	
	[[self scene] renderScene]; 		
}



-(void)syncStopped{
	//Redraw menu
	[self _updateMenu];
	

	//Still did not found a cleaner way to force a redraw of the menuitems
	NSArray* co = [self controls];
	int a;
	for(a=0;a<[co count];a++){
		BRControl* bc = [co objectAtIndex:a];
		[[bc layer] reload]; 
	}	
	[[self scene] renderScene]; 		

}

//Called after the sync process but before existing clips/channels are deleted from mem
-(void)syncWillFinish{ 
}



//Update menu after sync
-(void)_updateMenu{
	//Sync the RootChannels
	NSDictionary* rootChannels = [[CTV GetInstance] rootChannels];
	
	CTVRootChannel* rootChannel;
	CTVMainMenuElement* menuElement;
	CTVMainMenuElement* updatedMenuElement;
	NSEnumerator* channelEnum = [rootChannels objectEnumerator];
	while(rootChannel = [channelEnum nextObject]){
		//Check if the rootChannel is already in the menu
		NSEnumerator* menuEnum = [m_mainMenuElements objectEnumerator];
		updatedMenuElement = nil;
		while(menuElement = [menuEnum nextObject]){
			if( [menuElement rootChannel] == rootChannel ){
				//Found
				updatedMenuElement = menuElement;
				break;
			}
		}
		
		if(updatedMenuElement == nil){
			updatedMenuElement = [[CTVMainMenuElement alloc] init];
			[m_mainMenuElements insertObject:updatedMenuElement atIndex:0]; 
		}
		
		
		[updatedMenuElement setType:CTVMainMenuElementType_ROOTCHANNEL];
		[updatedMenuElement setTitle:[rootChannel name]];
		[updatedMenuElement setRootChannel:rootChannel];
		[updatedMenuElement setFunction:@selector(showRootChannel:)];	
		[updatedMenuElement setIconName:@"channels" /*[rootChannel iconUrlString]*/];
	}
	

	int sel = [(BRListControl*)[self list] selection]; //0 based
	
	[[self list] removeDividers];
	if([[[CTV GetInstance] rootChannels] count] > 0){		
		[[self list] setDividerIndex:[m_mainMenuElements count]-2];
	}
	//Some control for our selection selector 
	long max = 0.0 + [m_mainMenuElements count];
	if ( sel >= max ){
		[(BRListControl*)[self list] setSelection:max-1];		
	}else{
		[(BRListControl*)[self list] setSelection:sel]; //because setDeviderIndex changed the position		
	}
}


- (id)popAnimation{
	id animation = [super popAnimation];
	return animation;
}

- (id)pushAnimation{
	id animation = [super pushAnimation];
	return animation;
}



//Controller will be displayed on screen 
- (void)willBePushed{
	//Subscribe for sync events (menu updates)
	[[CTVSync GetInstance] addListener:(CTVSyncListener*)self];
	[(CTVAutoUpdate*)[CTVAutoUpdate GetInstance] addListener:(CTVAutoUpdateListener*)self];
	[super willBePushed];


	//BRTexture* icon = [self listIcon];
			
	NSString* iconPath =  [[NSBundle bundleForClass: [self class]] pathForResource:@"logo" ofType: @"png"];
	BRTexture * tex = [CTVCache createBitmapTextureFromPath:iconPath withScene:[self scene]];	

	//Animate from icon to tex 

	[self setListIcon:tex];

}



//Controller will be taken from screen
- (void)willBePopped{
	//Unsubscribe for sync events
	[[CTVSync GetInstance] removeListener:(CTVSyncListener*)self];
	[(CTVAutoUpdate*)[CTVAutoUpdate GetInstance] removeListener:(CTVAutoUpdateListener*)self];

	[super willBePopped];
}


- (void)wasExhumedByPoppingController:(id)fp8{
	//Redraw menu
	[self loadMenu];
//	[self _updateMenu];
	[super wasExhumedByPoppingController:fp8];
}

//@protocol CTVAutoUpdateListener
-(void)autoUpdateCheckDone:(NSString*)version{
	if([[CTVAutoUpdate GetInstance] updateAvailable]){
		//Only if this screen is not already on
		id activeController = [[self stack] peekController];
		if([activeController isKindOfClass:[CTVAutoUpdateController class]]){
			NSLog(@"Update is already on screen");
		}else{
			NSLog(@"New Update  screen");
			CTVAutoUpdateController* controller = [[[CTVAutoUpdateController alloc] initWithScene:[self scene]] autorelease];
			[[self stack] pushController: controller];
		}
	}  
}

-(void)autoUpdateCheckFail{
}




@end




/****************************************************************************************************************************/




/*
 * CTVMainMenuElement
 */
@implementation CTVMainMenuElement

-(id)init{
	[super init];
	
	return self;
}

-(void)dealloc{
	
	if(m_title)
		[m_title release];
	if(m_rootChannel)
		[m_rootChannel release];

	[super dealloc];
}

-(void)setTitle:(NSString*)title{
	if(m_title)
		[m_title release];
	[title retain];
	m_title = title;
}
-(NSString*)title{
	return m_title;
}

-(void)setRootChannel:(CTVRootChannel*)rootChannel{
	if(m_rootChannel)
		[m_rootChannel release];
	[rootChannel retain];
	m_rootChannel = rootChannel;
}
-(CTVRootChannel*)rootChannel{
	return m_rootChannel;
}

-(void)setType:(CTVMainMenuElementType)type{
	m_type = type;
}
-(CTVMainMenuElementType)type{
	return m_type;
}

-(void)setFunction:(SEL)function{
	m_function = function;
}
-(SEL)function{
	return m_function;
}
-(NSString*)iconName{
	return m_iconName;
}
-(void)setIconName:(NSString*)urlString{
	if(m_iconName)
		[m_iconName release];
	[urlString retain];
	m_iconName = urlString;
}





@end
